package org.news.web.service.impl;
import org.apache.commons.collections4.CollectionUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.green.model.v20180509.TextScanRequest;
import com.aliyuncs.http.FormatType;
import com.aliyuncs.http.HttpResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.system.domain.SysOss;
import org.dromara.system.mapper.SysOssMapper;
import org.news.web.constant.NewSroce;
import org.news.web.constant.NewsConstant;
import org.news.web.domain.*;
import org.news.web.mapper.*;
import org.news.web.redis.RedisConstant;
import org.news.web.service.INotificationsService;
import org.news.web.utils.HotRankUtils;
import org.news.web.utils.KeywordExtractorUtils;
import org.news.web.utils.TYutils;
import org.springframework.stereotype.Service;
import org.news.web.domain.bo.NewsBo;
import org.news.web.domain.vo.NewsVo;
import org.news.web.service.INewsService;

import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 新闻功能Service业务层处理
 *
 * @author Gu Ci
 * @date 2024-04-03
 */
@RequiredArgsConstructor
@Service
public class NewsServiceImpl implements INewsService {

    private final NewsMapper baseMapper;

    private final SysOssMapper SysOssMapper;

    private final CreatorsMapper creatorsMapper;

    private final CategoriesMapper categoriesMapper;

    private final UsersMapper usersMapper;

    private final INotificationsService notificationsService;

    private final TagsMapper tagsMapper;


    private final NewsMapper newsMapper;

    /**
     * 查询新闻功能
     */
    @Override
    public NewsVo queryById(Long newsId){
        return baseMapper.selectVoById(newsId);
    }

    /**
     * 查询新闻功能列表
     */
    @Override
    public TableDataInfo<NewsVo> queryPageList(NewsBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<News> lqw = buildQueryWrapper(bo);
        Page<NewsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        /**
         * 通过图片ossid 来获取图片链接
         */
        if(ObjectUtils.isNotEmpty(result) && !result.getRecords().isEmpty()){

            List<NewsVo> records = result.getRecords();

            Set<String> coverOssIds = records.stream().map((item -> {
                return item.getCover();
            })).collect(Collectors.toSet());




            Set ossIds = new HashSet();
            ossIds.addAll(coverOssIds);

            List filterIds = ossIds.stream().toList();

            List<SysOss> pts = SysOssMapper.selectList(new QueryWrapper<SysOss>().in("oss_id", filterIds));

            for(int i=0;i<records.size();i++){
                for(int j=0;j< pts.size();j++){
                    if(records.get(i).getCover().equals(String.valueOf(pts.get(j).getOssId()))){
                        records.get(i).setCoverUrl(pts.get(j).getUrl());
                    }
                }
            }
        }
        /**
         * 通过创作者id获取name
         */
        if(ObjectUtils.isNotEmpty(result) && !result.getRecords().isEmpty()){
            Set<Long> CreatorList = result.getRecords().stream().filter(item->{
                return Long.valueOf(item.getAuthorType())  == NewsConstant.CREATORS_CODE.longValue();
            }).map(item -> {
                return Long.valueOf(item.getAuthor());
            }).collect(Collectors.toSet());
            Set<Long> CategorsList = result.getRecords().stream().filter(item->{
                return Long.valueOf(item.getAuthorType()) == NewsConstant.LM_CODE.longValue();
            }).map(item -> {
                return Long.valueOf(item.getAuthor());
            }).collect(Collectors.toSet());


            if(CreatorList != null && CreatorList.size()>0){
                //作者
                List<Creators> creators = creatorsMapper.selectList(new LambdaQueryWrapper<Creators>().in(Creators::getCreatorId,CreatorList));

                Set<Long> collect1 = creators.stream().map((item -> {
                    return item.getUserId();
                })).collect(Collectors.toSet());
                //通过作者获取用户信息
                List<Users> users = usersMapper.selectList(new LambdaQueryWrapper<Users>().in(Users::getUserId,
                    collect1
                ));
//
                users.stream().forEach(
                    user ->{
                        creators.stream().forEach(
                            ct ->{
                                if(ct.getUserId() == user.getUserId()){
                                    user.setUserId(ct.getCreatorId());
                                }
                            }
                        );
                    }
                );
//                用users来获取用户名
                users.stream().forEach(
                    user->{
                        result.getRecords().stream().forEach(
                            news ->{
                                if(user.getUserId() == Long.valueOf(news.getAuthor())){
                                    news.setAuthorName(user.getUsername());
                                }
                            }
                        );
                    }
                );
            }
            if(CategorsList != null && CategorsList.size()>0){
                List<Categories> categories = categoriesMapper.selectList(new LambdaQueryWrapper<Categories>().in(Categories::getCategoryId, CategorsList));
                if(categories != null){
                    categories.stream().forEach(
                        cate ->{
                            result.getRecords().forEach(
                                news ->{
                                    if(cate.getCategoryId() == Long.valueOf(news.getAuthor())){
                                        news.setAuthorName(cate.getCategoryName());
                                    }
                                }
                            );
                        }
                    );
                }
            }
        }


        return TableDataInfo.build(result);
    }

    /**
     * 查询新闻功能列表
     */
    @Override
    public List<NewsVo> queryList(NewsBo bo) {
        LambdaQueryWrapper<News> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<News> buildQueryWrapper(NewsBo bo) {
        LambdaQueryWrapper<News> lqw = Wrappers.lambdaQuery();

        if(bo.getCategories() != null && bo.getCategories().split(",").length>0){
            String[] split = bo.getCategories().split(",");
            lqw.in(StringUtils.isNotBlank(bo.getCategories()), News::getCategories, split);
        }

        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), News::getTitle, bo.getTitle());
        lqw.eq(StringUtils.isNotBlank(bo.getCover()), News::getCover, bo.getCover());
        lqw.eq(StringUtils.isNotBlank(bo.getContent()), News::getContent, bo.getContent());
        lqw.eq(StringUtils.isNotBlank(bo.getIntroduction()), News::getIntroduction, bo.getIntroduction());
        lqw.eq(StringUtils.isNotBlank(bo.getAuthor()), News::getAuthor, bo.getAuthor());
        lqw.eq(StringUtils.isNotBlank(bo.getAuthorType()), News::getAuthorType, bo.getAuthorType());
        lqw.eq(bo.getApplyStatus() != null, News::getApplyStatus, bo.getApplyStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getApplyInfo()), News::getApplyInfo, bo.getApplyInfo());
        lqw.eq(bo.getPublishTime() != null, News::getPublishTime, bo.getPublishTime());
        lqw.eq(bo.getCreationTime() != null, News::getCreationTime, bo.getCreationTime());
        lqw.eq(StringUtils.isNotBlank(bo.getTags()), News::getTags, bo.getTags());
        lqw.eq(bo.getViews() != null, News::getViews, bo.getViews());
        lqw.eq(bo.getLikes() != null, News::getLikes, bo.getLikes());
        lqw.eq(bo.getFavorites() != null, News::getFavorites, bo.getFavorites());
        lqw.eq(bo.getHotness() != null, News::getHotness, bo.getHotness());
        lqw.eq(bo.getComments() != null, News::getComments, bo.getComments());
        return lqw;
    }

    /**
     * 新增新闻功能
     */
    @Override
    public Boolean insertByBo(NewsBo bo) throws UnsupportedEncodingException, ClientException {
        News add = MapstructUtils.convert(bo, News.class);
        validEntityBeforeSave(add);
        DFInsertDO(add);
        /**
         * 判断是否为待审核
         */
//        if(bo.getApplyStatus() == 1){
//           ShenHeFaBU(add);
//        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setNewsId(add.getNewsId());
        }
        return flag;
    }
    /**
     * 发布状态审核
     */
    public boolean ShenHeFaBU(News news) throws ClientException, UnsupportedEncodingException {

        IClientProfile profile = DefaultProfile
            .getProfile("cn-shanghai",
                "LTAI5tF8BUp2r4hnCd9UKNeu",
                "FW2SVjjQtvgZmlYz3lW4POIZTC6s9w");
        DefaultProfile
            .addEndpoint("cn-shanghai", "cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
        IAcsClient client = new DefaultAcsClient(profile);
        TextScanRequest textScanRequest = new TextScanRequest();
        textScanRequest.setAcceptFormat(FormatType.JSON); // 指定API返回格式。
        textScanRequest.setHttpContentType(FormatType.JSON);
        textScanRequest.setMethod(com.aliyuncs.http.MethodType.POST); // 指定请求方法。
        textScanRequest.setEncoding("UTF-8");
        textScanRequest.setRegionId("cn-shanghai");
        List<Map<String, Object>> tasks = new ArrayList<Map<String, Object>>();
        Map<String, Object> task1 = new LinkedHashMap<String, Object>();
        task1.put("dataId", UUID.randomUUID().toString());
        /**
         * 待检测的文本，长度不超过10000个字符。
         */
        task1.put("content", news.getContent());
        tasks.add(task1);
        JSONObject data = new JSONObject();
        /**
         * 检测场景。 文字敏感内容 文字违禁内容
         **/
        data.put("scenes", Arrays.asList("politics","contraband"));
        data.put("tasks", tasks);
        System.out.println("参数："+ JSON.toJSONString(data, true));
        textScanRequest.setHttpContent(data.toJSONString().getBytes("UTF-8"), "UTF-8", FormatType.JSON);
        // 请务必设置超时时间。
        textScanRequest.setConnectTimeout(3000);
        textScanRequest.setReadTimeout(6000);
        try {
            HttpResponse httpResponse = client.doAction(textScanRequest);
            if(httpResponse.isSuccess()){
                JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
                System.out.println("结果："+JSON.toJSONString(scrResponse, true));
                if (200 == scrResponse.getInteger("code")) {
                    JSONArray taskResults = scrResponse.getJSONArray("data");
                    for (Object taskResult : taskResults) {
                        if(200 == ((JSONObject)taskResult).getInteger("code")){
                            JSONArray sceneResults = ((JSONObject)taskResult).getJSONArray("results");
                            for (Object sceneResult : sceneResults) {
                                String scene = ((JSONObject)sceneResult).getString("scene");
                                String suggestion = ((JSONObject)sceneResult).getString("suggestion");
                                //根据scene和suggetion做相关处理。
                                //suggestion == pass表示未命中垃圾。suggestion == block表示命中了垃圾，可以通过label字段查看命中的垃圾分类。
                                System.out.println("args = [" + scene + "]");
                                System.out.println("args = [" + suggestion + "]");
                            }
                        }else{
                            System.out.println("task process fail:" + ((JSONObject)taskResult).getInteger("code"));
                        }
                    }
                } else {
                    System.out.println("detect not success. code:" + scrResponse.getInteger("code"));
                }
            }else{
                System.out.println("response not success. status:" + httpResponse.getStatus());
            }
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }



        //      todo     如果是提交 也就是待审核状态 会进行自动审核
        //            如果机器审核未通过会进行把状态修改为人工审核

        //       todo      如果机器审核通过会进行把状态 并且达到发布状态时间 修改为发布
        //            否则就会修改为审核通过
        return false;
    }

    /**
     * 添加默认值
     * @param bo
     */
    private void DFInsert(NewsBo bo) {
        bo.setFavorites(NewsConstant.DF_favorites);
        bo.setLikes(NewsConstant.DF_likes);
        bo.setViews(NewsConstant.DF_views);
        bo.setComments(NewsConstant.DF_comments);
        bo.setHotness(NewsConstant.DF_hotness);
//        提供关键字
        bo.setRelatedKey(getRelateKey(bo));
    }

    private void DFInsertDO(News bo) {
        bo.setFavorites(NewsConstant.DF_favorites);
        bo.setLikes(NewsConstant.DF_likes);
        bo.setViews(NewsConstant.DF_views);
        bo.setComments(NewsConstant.DF_comments);
        bo.setHotness(NewsConstant.DF_hotness);
//        提供关键字
        bo.setRelatedKey(getRelateKeyDO(bo));
    }

    /**
     * 分词获取关键字
     * @return
     */
    public String getRelateKey(NewsBo bo) {
        StringBuilder keyStr = null;
        if (bo != null && StringUtils.isNotBlank(bo.getContent())) {
            Document doc = Jsoup.parse(bo.getContent());
            String text = doc.text();
            System.out.println("text:" + text);
            List<String> keys = KeywordExtractorUtils.extractKeywords(text);
//            过滤掉停用词
//            获取前5个关键词
            HashMap<String, Integer> keyCounts = new HashMap<>();
            keys.forEach(
                key -> {
                    if (!TYutils.contiansKey(key)) {
                        if (keyCounts.containsKey(key)) {
                            keyCounts.put(key, keyCounts.get(key) + 1);
                        } else {
                            keyCounts.put(key, 1);
                        }
                    }
                }
            );
//            遍历hashmap
            List<Map.Entry<String, Integer>> collect = keyCounts.entrySet().stream().collect(Collectors.toList());
            List<Map.Entry<String, Integer>> collect1 = collect.stream().sorted((item1, item2) -> {
                return item2.getValue() - item1.getValue();
            }).collect(Collectors.toList());
            System.out.println(collect1);
//            获取前5个关键字
            int keyCount = 5;
            int i = 0;
            keyStr = new StringBuilder();
            while (i < keyCount) {
                if (i >= collect1.size()) {
                    break;
                }
                keyStr.append(collect1.get(i).getKey());
                keyStr.append(",");
                i++;
            }
            if(keyStr.length()>0){
                keyStr.deleteCharAt(keyStr.length() - 1);
            }
        }
        System.out.println("新闻key：" + keyStr);
        return keyStr.toString();
    }


    public String getRelateKeyDO(News bo) {
        StringBuilder keyStr = null;
        if (bo != null && StringUtils.isNotBlank(bo.getContent())) {
            Document doc = Jsoup.parse(bo.getContent());
            String text = doc.text();
            System.out.println("text:" + text);
            List<String> keys = KeywordExtractorUtils.extractKeywords(text);
//            过滤掉停用词
//            获取前5个关键词
            HashMap<String, Integer> keyCounts = new HashMap<>();
            keys.forEach(
                key -> {
                    if (!TYutils.contiansKey(key)) {
                        if (keyCounts.containsKey(key)) {
                            keyCounts.put(key, keyCounts.get(key) + 1);
                        } else {
                            keyCounts.put(key, 1);
                        }
                    }
                }
            );
//            遍历hashmap
            List<Map.Entry<String, Integer>> collect = keyCounts.entrySet().stream().collect(Collectors.toList());
            List<Map.Entry<String, Integer>> collect1 = collect.stream().sorted((item1, item2) -> {
                return item2.getValue() - item1.getValue();
            }).collect(Collectors.toList());
            System.out.println(collect1);
//            获取前5个关键字
            int keyCount = 5;
            int i = 0;
            keyStr = new StringBuilder();
            while (i < keyCount) {
                if (i >= collect1.size()) {
                    break;
                }
                keyStr.append(collect1.get(i).getKey());
                keyStr.append(",");
                i++;
            }
            keyStr.deleteCharAt(keyStr.length() - 1);

        }
        System.out.println("新闻key：" + keyStr);
        return keyStr.toString();
    }


    /**
     * 修改新闻功能
     */
    @Override
    public Boolean updateByBo(NewsBo bo) {
        News update = MapstructUtils.convert(bo, News.class);
        News news = baseMapper.selectById(bo.getNewsId());
        if(news.getApplyStatus() != update.getApplyStatus()){
             //如果不等于 判断是否把状态修改为其他
//           前提是作者
            if(Long.valueOf(bo.getAuthorType()) == NewsConstant.CREATORS_CODE){
                if(update.getApplyStatus() == 2 | update.getApplyStatus() == 8 | update.getApplyStatus() == 9){
                    //给用户发送消息
                    /**
                     * 获取用户id
                     */
                    Creators creators = creatorsMapper.selectById(update.getAuthor());
                    String msg = "";
                    if(update.getApplyStatus() == 2){
                        msg = "你的新闻：标题为:<<"+bo.getTitle()+">> 未通过 审核";
                    }
                    if(update.getApplyStatus() == 8){
                        msg = "你的新闻：标题为:<<"+bo.getTitle()+">> 通过审核";
                    }
                    if(update.getApplyStatus() == 9){
                        msg = "你的新闻：标题为:<<"+bo.getTitle()+">> 已经发布";
                    }
                    notificationsService.sendSystemMsg(creators.getUserId(),msg);
                }
            }
        }
        validEntityBeforeSave(update);
//       更新关键字
        String relateKey = getRelateKey(bo);
        System.out.println("relateKey"+relateKey);
        update.setRelatedKey(relateKey);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(News entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除新闻功能
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
//        给用户发送删除文章消息
        List<NewsVo> newsVos = baseMapper.selectVoList(new LambdaQueryWrapper<News>().in(News::getNewsId, ids));
        newsVos.stream().filter(
            item->{
                return Long.valueOf(item.getAuthorType()) == NewsConstant.CREATORS_CODE;
            }
        ).forEach(item ->{
//          发送信息
            /**
             * 获取用户id
             */
            Creators creators = creatorsMapper.selectById(item.getAuthor());
            /**
             * 删除新闻缓存
             */
            deleteNewsRedis(item.getNewsId());
            notificationsService.sendSystemMsg(creators.getUserId(),"你的新闻：标题：<<"+item.getTitle()+">> 已经被系统删除");

        });
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<NewsVo> FBlist(String key) {
        if(key == null){
            key = "";
        }
        List<NewsVo> newsVos = baseMapper.selectVoList(new LambdaQueryWrapper<News>().eq(News::getApplyStatus, NewsConstant.FaBu).like(News::getTitle, key));
        return  newsVos;
    }

    @Override
    public void setNewsImg(List<NewsVo> newsVos) {

        if(ObjectUtils.isNotEmpty(newsVos) && newsVos.size() != 0){

            List<NewsVo> records = newsVos;

            Set<String> coverOssIds = records.stream().map((item -> {
                return item.getCover();
            })).collect(Collectors.toSet());




            Set ossIds = new HashSet();
            ossIds.addAll(coverOssIds);

            List filterIds = ossIds.stream().toList();

            List<SysOss> pts = SysOssMapper.selectList(new QueryWrapper<SysOss>().in("oss_id", filterIds));

            for(int i=0;i<records.size();i++){
                for(int j=0;j< pts.size();j++){
                    if(records.get(i).getCover().equals(String.valueOf(pts.get(j).getOssId()))){
                        records.get(i).setCoverUrl(pts.get(j).getUrl());
                    }
                }
            }
        }

    }

    @Override
    public TableDataInfo<NewsVo> getNow(NewsBo bo, PageQuery pageQuery) {
//        必须是已经发布的内容
        bo.setApplyStatus(NewsConstant.FaBu);
        TableDataInfo<NewsVo> newsVoTableDataInfo = queryPageList(bo, pageQuery);
        setNewsTag(newsVoTableDataInfo.getRows());
        return newsVoTableDataInfo;
    }

    /**
     * 获取热门排行榜
     * @return
     */
    @Override
    public List<NewsVo> getHot() {
        List<Integer> hotRanking = HotRankUtils.getHotRanking();
        if(ObjectUtils.isEmpty(hotRanking) && hotRanking.size() == 0){
            return null;
        }
        String fieldOrder = getFieldOrder(hotRanking);
        if(fieldOrder.equals("")){
            throw new ServiceException("数据故障");
        }
        List<NewsVo> newsVos =newsMapper.getHotRankIng(fieldOrder);
        return newsVos;
    }

    private <T> String getFieldOrder(List<T> ids) {
        StringBuilder fieldOrder = new StringBuilder();
        for (T id : ids) {
            fieldOrder.append(id).append(",");
        }
        fieldOrder.deleteCharAt(fieldOrder.length()-1);
        return fieldOrder.toString();
    }

    /**
     * 获取相关新闻
     * @param newId
     * @return
     */
    @Override
    public List<NewsVo> getRelateNews(Long newId) {
//        todo 缓存

        // 1.获取当前新闻的关键字 和其他所有新闻的关键字
//        获取当前所有 已经发布的新闻
        List<News> news = newsMapper.selectList(new LambdaQueryWrapper<News>().select(News::getNewsId, News::getRelatedKey).eq(News::getApplyStatus, NewsConstant.FaBu));
//        查找是newid的新闻
        int index = -1;
        for(int i=0;i<news.size();i++){
            if(newId.longValue() == news.get(i).getNewsId().longValue()){
                index = i;
                break;
            }
        }
        if(index == -1){
            throw new ServiceException("该新闻不存在!!");
        }
        News curNew = news.remove(index);
        //获取新闻id + 得分 进行排序
        ArrayList<NewSroce> newSroces = new ArrayList<>();
        String[] a = curNew.getRelatedKey().split(",");
        for(int i=0;i<news.size();i++){
            News newsItem = news.get(i);
            if(newsItem.getRelatedKey() == null || newsItem.getRelatedKey().equals("")){
                continue;
            }
            String[] b = newsItem.getRelatedKey().split(",");
            if((a != null &&  b != null ) &&  (a.length > 0 &&  b.length > 0)){
                newSroces.add(new NewSroce(newsItem.getNewsId(),XGD(a,b)));
            }
        }
//        排序倒序排列
        Collections.sort(newSroces, new Comparator<NewSroce>() {
            @Override
            public int compare(NewSroce o1, NewSroce o2) {
                return Float.compare(o2.getScore(),o1.getScore());
            }
        });


//       获取前5个相关新闻id 在获取相关信息
        int KeyGetCount = 5;
        ArrayList<Long> keysId = new ArrayList<>();
        int i=0;
        while(i<KeyGetCount){
            if(i >= newSroces.size()){
                break;
            }
            keysId.add(newSroces.get(i).getNewId());
            i++;
        }
//      没有相关新闻
        if(keysId.size() ==0){
            return null;
        }
//       通过id查询相关新闻信息
        List<NewsVo> newsVoList = newsMapper.selectVoList(new LambdaQueryWrapper<News>().in(News::getNewsId, keysId));

        setNewsAuthorName(newsVoList);
        setNewsImg(newsVoList);

        return newsVoList;
    }


    public float XGD(String a[],String b[]){
        Collection<String> union = CollectionUtils.union(Arrays.asList(a), Arrays.asList(b));
        Collection<String> intersection = CollectionUtils.intersection(Arrays.asList(a), Arrays.asList(b));

        if(intersection.size() == 0){
            return 0.0f;
        }

        return Float.valueOf(intersection.size())/Float.valueOf(union.size());
    }

    @Override
    public NewsVo getNewsById(Integer id) {
        NewsVo newsVo = baseMapper.selectVoById(id);
        SysOss sysOss = SysOssMapper.selectById(newsVo.getCover());
        newsVo.setCoverUrl(sysOss.getUrl());
        return newsVo;
    }

    @Override
    public boolean addView(Long userId, Long newId) {
//        1.添加用户行为
        RedisUtils.addCacheSet(RedisConstant.XIN_WEI + ":" + userId,newId);
        RedisUtils.setCacheMapValue(RedisConstant.XIN_WEI + ":" + userId + ":" + newId,RedisConstant.IS_VIEW,1);
//        2.更新数据库数据
        int update = baseMapper.update(new LambdaUpdateWrapper<News>().eq(News::getNewsId, newId).setSql("views = views+1"));
        return update>0;
    }

    @Override
    public Long getLikeCount(Long id) {
        if(id == null || id == 0){
            throw new ServiceException("不存在的新闻数据!");
        }
        return Long.valueOf(RedisUtils.getCacheSet(RedisConstant.NEWS_PRE_KEY +":"+RedisConstant.LIKE_PRE_KEY+":"+id).size());
    }

    @Override
    public Long getFavoCount(Long id) {
        if(id == null || id == 0){
            throw new ServiceException("不存在的新闻数据!");
        }
        return Long.valueOf(RedisUtils.getCacheSet(RedisConstant.NEWS_PRE_KEY +":"+RedisConstant.FAVO_PRE_KEY+":"+id).size());
    }

    @Override
    public Long AuthorAllViewCount(Long id) {
        return baseMapper.AuthorAllViewCount(id);
    }

    @Override
    public Long AuthorAllCommCount(Long id) {
        return baseMapper.AuthorAllCommCount(id);
    }

//    @Override
//    public boolean Fove(Long userId, Long newId) {
////        1.添加用户行为
//        RedisUtils.addCacheSet(RedisConstant.XIN_WEI + ":" + userId,newId);
//        RedisUtils.setCacheMapValue(RedisConstant.XIN_WEI + ":" + userId + ":" + newId,RedisConstant.IS_VIEW,1);
////        2.更新数据库数据
//        int update = baseMapper.update(new LambdaUpdateWrapper<News>().eq(News::getNewsId, newId).setSql("favorites = favorites+1"));
//        return update>0;
//    }
//
//    public boolean isFove(){
//
//    }
//
//
//    public boolean isLike(){
//
//    }

//    @Override
//    public boolean Like(Long userId, Long newId) {
////        1.添加用户行为
//        RedisUtils.addCacheSet(RedisConstant.XIN_WEI + ":" + userId,newId);
//        RedisUtils.setCacheMapValue(RedisConstant.XIN_WEI + ":" + userId + ":" + newId,RedisConstant.IS_LIKE,1);
////        2.更新数据库数据
//        int update = baseMapper.update(new LambdaUpdateWrapper<News>().eq(News::getNewsId, newId).setSql("likes = likes+1"));
//        return update>0;
//    }

    /**
     * 创建新闻缓存   创建 游览量 点赞 收藏 评论
     *  不需要的
     *  规则  新闻:点赞：id   新闻:收藏：id  新闻:游览：id  新闻:评论：id
     */
    public boolean createNewsRedis(Long newsId){
        /**
         * 创建
         */
//        RedisUtils.addCacheSet(RedisConstant.NEWS_PRE_KEY,1);
        return false;
    }


    /**
     * 删除新闻缓存 删除 游览量 点赞 收藏 评论
     */
    public boolean deleteNewsRedis(Long newsId){
        String StrLike = RedisConstant.NEWS_PRE_KEY+":"+RedisConstant.LIKE_PRE_KEY+":"+newsId;
        String StrView = RedisConstant.NEWS_PRE_KEY+":"+RedisConstant.VIEW_PRE_KEY+":"+newsId;
        String StrFavo = RedisConstant.NEWS_PRE_KEY+":"+RedisConstant.FAVO_PRE_KEY+":"+newsId;
        String StrComm = RedisConstant.NEWS_PRE_KEY+":"+RedisConstant.COMM_PRE_KEY+":"+newsId;
        RedisUtils.deleteKeys(StrLike);
        RedisUtils.deleteKeys(StrView);
        RedisUtils.deleteKeys(StrFavo);
        RedisUtils.deleteKeys(StrComm);
        return true;
    }

    @Override
    public void setNewsAuthorName(List<NewsVo> newsVos) {
        List<NewsVo> result = newsVos;
        if (ObjectUtils.isNotEmpty(result) && result.size() > 0) {
            Set<Long> CreatorList = result.stream().filter(item -> {
                return Long.valueOf(item.getAuthorType()) == NewsConstant.CREATORS_CODE.longValue();
            }).map(item -> {
                return Long.valueOf(item.getAuthor());
            }).collect(Collectors.toSet());
            Set<Long> CategorsList = result.stream().filter(item -> {
                return Long.valueOf(item.getAuthorType()) == NewsConstant.LM_CODE.longValue();
            }).map(item -> {
                return Long.valueOf(item.getAuthor());
            }).collect(Collectors.toSet());


            if (CreatorList != null && CreatorList.size() > 0) {
                //作者
                List<Creators> creators = creatorsMapper.selectList(new LambdaQueryWrapper<Creators>().in(Creators::getCreatorId, CreatorList));

                Set<Long> collect1 = creators.stream().map((item -> {
                    return item.getUserId();
                })).collect(Collectors.toSet());
                //通过作者获取用户信息
                List<Users> users = usersMapper.selectList(new LambdaQueryWrapper<Users>().in(Users::getUserId,
                    collect1
                ));
                //
                users.stream().forEach(
                    user -> {
                        creators.stream().forEach(
                            ct -> {
                                if (ct.getUserId() == user.getUserId()) {
                                    user.setUserId(ct.getCreatorId());
                                }
                            }
                        );
                    }
                );
                //                用users来获取用户名
                users.stream().forEach(
                    user -> {
                        result.stream().forEach(
                            news -> {
                                if (user.getUserId() == Long.valueOf(news.getAuthor())) {
                                    news.setAuthorName(user.getUsername());
                                }
                            }
                        );
                    }
                );
            }
            if (CategorsList != null && CategorsList.size() > 0) {
                List<Categories> categories = categoriesMapper.selectList(new LambdaQueryWrapper<Categories>().in(Categories::getCategoryId, CategorsList));
                if (categories != null) {
                    categories.stream().forEach(
                        cate -> {
                            result.forEach(
                                news -> {
                                    if (cate.getCategoryId() == Long.valueOf(news.getAuthor())) {
                                        news.setAuthorName(cate.getCategoryName());
                                    }
                                }
                            );
                        }
                    );
                }
            }
        }
    }

    @Override
    public int updateStatus(NewsBo bo) {
        News news = MapstructUtils.convert(bo, News.class);
        return baseMapper.updateById(news);
    }

    public void setNewsTag(List<NewsVo> newsVos) {
        Set<String> tadIds = new HashSet<>();
        if(newsVos!=null && newsVos.size() >0){
            newsVos.forEach(
                news ->{
                    if(StringUtils.isNotBlank(news.getTags())){
                        tadIds.addAll(
                            Arrays.stream(news.getTags().split(",")).collect(Collectors.toSet())
                        );
                    }
                }
            );
            if(tadIds.size() == 0){
                return;
            }
            List<Tags> tags = tagsMapper.selectList(new LambdaQueryWrapper<Tags>().in(Tags::getTagId, tadIds));
            newsVos.forEach(
                news ->{
                    if(StringUtils.isNotBlank(news.getTags())){
                        List<Tags> t = new ArrayList<>();
                        Set<String> collect = Arrays.stream(news.getTags().split(",")).collect(Collectors.toSet());
                        collect.forEach(
                            c ->{
                                tags.forEach(
                                    tag ->{
                                        if(tag.getTagId() == Long.valueOf(c)){
                                            t.add(tag);
                                        }
                                    }
                                );
                            }
                        );
                        news.setTagsName(t);
                    }
                }
            );
        }
    }
}
